package me.zhengjie.modules.quartz.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.common.util.RedisKeyUtil;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.domain.PropertyWaterMark;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.common.request.DataRequest;
import com.qiaofang.common.util.StringUtil;
import com.qiaofang.core.gatewayclient.GatewayTemplate;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.quartz.service.constants.SyncConstants;
import me.zhengjie.modules.quartz.service.dto.SyncCommon;
import me.zhengjie.modules.quartz.task.dto.PullV20WaterMarkDto;
import me.zhengjie.modules.quartz.task.dto.SearchManagementOptionDTO;
import me.zhengjie.modules.quartz.task.dto.V20WaterMarkDto;
import me.zhengjie.utils.RedisUtils;
import me.zhengjie.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author: youqing.yang
 * @Create: 2021/03/26 10:44
 * @Description:
 **/

@Slf4j
@Component
public class SynPropertyWaterMarkTask {

    private static final String PRO_WATER_MARK_SYNC_API = "/api/dataprocessing/syncData/getPropertyImgWatermark";

    private static final String V20_PRO_WATER_MARK_SYNC_API = "/api/jedisystem/mgtOption/searchManagementOption";

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private GatewayTemplate gatewayTemplate;

    private RestTemplate template;

    {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(300000);
        requestFactory.setReadTimeout(300000);
        template = new RestTemplate(requestFactory);
    }

    public void run() {
        log.info("SynPropertyWaterMarkTask run start");
        Corporation corporation = new Corporation();
        corporation.setDeleted(Boolean.FALSE);
        Iterable<Corporation> list = corporationService.findAll(Example.of(corporation));
        list.forEach(item -> {
            String corporationCode = item.getCorporationCode();
            if (StringUtil.isEmpty(item.getPullDomain())) {
                log.error("集团:{} 的同步数据域名未配置", corporationCode);
                return;
            }
            //处理v20公司水印
            if (item.getV20Flag()) {
                synV20WaterMarkConfig(item);
                return;
            }

            Criteria criteria = Criteria.where("corporationCode").is(corporationCode).and("status").is(1);
            List<CityCompany> companies = mongoTemplate.find(new Query(criteria), CityCompany.class);
            companies.forEach(company -> {
                SyncCommon syncCommon = new SyncCommon();
                syncCommon.setCorporationCode(item.getCorporationCode());
                syncCommon.setAppId(item.getPullAppId());
                syncCommon.setAppKey(item.getPullAppKey());
                syncCommon.setDomain(item.getPullDomain());
                syncCommon.setCityCode(company.getCityCode());
                syncCommon.setCompanyUuid(company.getCompanyUuid());

                log.info("开始处理公司:{}的房源图片水印数据，开始时间:{}", company.getCompanyUuid(), new Date());
                updatePropertyWaterMark(syncCommon, PRO_WATER_MARK_SYNC_API, company.getPropertyWaterMark());
                log.info("完成处理公司:{}的房源图片水印数据，结束时间:{}", company.getCompanyUuid(), new Date());
            });
        });
        log.info("SynPropertyWaterMarkTask run end");
    }

    private void updatePropertyWaterMark(SyncCommon syncCommon, String apiUrl, PropertyWaterMark propertyWaterMark) {
        PropertyWaterMark v10PropertyWaterMark = httpRequestData(syncCommon, apiUrl);

        if ((propertyWaterMark != null && v10PropertyWaterMark == null) || (propertyWaterMark == null && v10PropertyWaterMark != null)) {
            String propertyWaterMarkKey = RedisKeyUtil.getPropertyWaterMarkKey(syncCommon.getCompanyUuid());
            redisUtils.del(propertyWaterMarkKey);
        }

        if ((propertyWaterMark != null && v10PropertyWaterMark != null) && !(propertyWaterMark.equals(v10PropertyWaterMark))){
            String propertyWaterMarkKey = RedisKeyUtil.getPropertyWaterMarkKey(syncCommon.getCompanyUuid());
            redisUtils.del(propertyWaterMarkKey);
        }

        Criteria criteria = Criteria.where("companyUuid").is(syncCommon.getCompanyUuid());
        Update update = new Update();
        update.set("propertyWaterMark", v10PropertyWaterMark);
        mongoTemplate.updateFirst(new Query(criteria), update, CityCompany.class);
    }

    private HttpHeaders getHeaders(SyncCommon syncCommon) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("X-AUTH-APP-ID", syncCommon.getAppId());
        headers.add("X-AUTH-KEY", syncCommon.getAppKey());
        headers.add("companyUuid", syncCommon.getCompanyUuid());
        log.info("========>headers:{}", JSON.toJSONString(headers));
        return headers;
    }

    private PropertyWaterMark httpRequestData(SyncCommon syncCommon, String apiUrl) {
        HttpHeaders headers = getHeaders(syncCommon);
        DataRequest dataRequest = new DataRequest();
        String url = syncCommon.getDomain() + apiUrl;
        String result = null;
        log.info("sync params {},header {}", dataRequest, headers);
        try {
            result = template.postForObject(url, new HttpEntity<>(dataRequest, headers), String.class);
            log.info("sync result {}", result);
        } catch (Exception e) {
            log.error("httpRequest error", e);
        }

        if (Objects.isNull(result)) {
            return null;
        }
        JSONObject resultObject = JSON.parseObject(result);
        if (null == resultObject) {
            return null;
        }
        String responseCode = resultObject.getString("responseCode");
        if (!SyncConstants.ON.equals(responseCode)) {
            String responseMessage = resultObject.getString("responseMessage");
            log.info("sync error {}", responseMessage);
            return null;
        }
        if (Objects.isNull(resultObject)) {
            return null;
        }
        JSONObject data = resultObject.getJSONObject("data");
        return data.toJavaObject(PropertyWaterMark.class);
    }

    private void synV20WaterMarkConfig(Corporation corporation) {
        Criteria criteria = Criteria.where("corporationCode").is(corporation.getCorporationCode()).and("status").is(1);
        List<CityCompany> companies = mongoTemplate.find(new Query(criteria), CityCompany.class);
        companies.forEach(company -> {
            SyncCommon syncCommon = new SyncCommon();
            syncCommon.setCompanyUuid(company.getCompanyUuid());
            log.info("开始处理公司:{}的房源图片水印数据，开始时间:{}", company.getCompanyUuid(), new Date());
            updateV20PropertyWaterMark(syncCommon, V20_PRO_WATER_MARK_SYNC_API, company.getPropertyWaterMark());
            log.info("完成处理公司:{}的房源图片水印数据，结束时间:{}", company.getCompanyUuid(), new Date());
        });
    }

    private void updateV20PropertyWaterMark(SyncCommon syncCommon, String apiUrl, PropertyWaterMark propertyWaterMark) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("companyUuid", syncCommon.getCompanyUuid());

        List<String> paraNames = Lists.newArrayList("Watermark", "Watermark_type", "Watermark_content", "Watermark_url", "Watermark_align");
        PullV20WaterMarkDto pullV20WaterMarkDto = new PullV20WaterMarkDto();
        pullV20WaterMarkDto.setSearchManagementOptionDTO(SearchManagementOptionDTO.builder().paraNames(paraNames).build());

        JSONObject jsonObject;
        try {
            jsonObject = gatewayTemplate.postForObject(apiUrl, pullV20WaterMarkDto, headers , JSONObject.class);
            log.info("result is {}", JSON.toJSONString(jsonObject));
        } catch (Exception e) {
            log.error("同步20图片水印异常,公司：{},error：{}", syncCommon.getCompanyUuid(), e);
            throw new BusinessException("Synchronous v20 waterMark error");
        }
        if (jsonObject != null) {
            JSONObject objectJSONObject = jsonObject.getJSONObject("managementOptionResultDTO");

            if (!Objects.isNull(objectJSONObject)) {

                JSONArray jsonArray = objectJSONObject.getJSONArray("managementOptionList");
                List<V20WaterMarkDto> v20WaterMarkDtos = JSONObject.parseArray(jsonArray.toJSONString(), V20WaterMarkDto.class);

                PropertyWaterMark synPropertyWaterMark = new PropertyWaterMark();

                v20WaterMarkDtos.forEach(V20WaterMarkDto -> {
                    switch (V20WaterMarkDto.getParaName()) {
                        case "Watermark":
                            synPropertyWaterMark.setWatermark(V20WaterMarkDto.getParaValue());
                            break;
                        case "Watermark_type":
                            synPropertyWaterMark.setWatermarkType(StringUtils.equals("text", V20WaterMarkDto.getParaValue()) ? "0" : "1");
                            break;
                        case "Watermark_content":
                            synPropertyWaterMark.setWatermarkContent(V20WaterMarkDto.getParaValue());
                            break;
                        case "Watermark_url":
                            synPropertyWaterMark.setWatermarkUrl("https:" + V20WaterMarkDto.getParaValue());
                            break;
                        case "Watermark_align":
                            synPropertyWaterMark.setWatermarkAlign(V20WaterMarkDto.getParaValue());
                            break;
                    }
                });

                if ((propertyWaterMark != null && synPropertyWaterMark == null) || (propertyWaterMark == null && synPropertyWaterMark != null)) {
                    String propertyWaterMarkKey = RedisKeyUtil.getPropertyWaterMarkKey(syncCommon.getCompanyUuid());
                    redisUtils.del(propertyWaterMarkKey);
                }

                if ((propertyWaterMark != null && synPropertyWaterMark != null) && !(propertyWaterMark.equals(synPropertyWaterMark))) {
                    String propertyWaterMarkKey = RedisKeyUtil.getPropertyWaterMarkKey(syncCommon.getCompanyUuid());
                    redisUtils.del(propertyWaterMarkKey);
                }

                if (synPropertyWaterMark.equals(propertyWaterMark)) {
                    return;
                }

                Criteria criteria = Criteria.where("companyUuid").is(syncCommon.getCompanyUuid());
                Update update = new Update();
                update.set("propertyWaterMark", synPropertyWaterMark);
                mongoTemplate.updateFirst(new Query(criteria), update, CityCompany.class);
            }
        }
    }
}
